home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Arashi 1.1.1 / source code / Game Source / jam src / STPlayer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-25  |  17.0 KB  |  812 lines  |  [TEXT/KAHL]

  1. /*/
  2.      Project Arashi: STPlayer.c
  3.      Major release: Version 1.1d2, 9/5/95
  4.  
  5.      Last modification: Friday, November 25, 1994, 6:06
  6.      Created: Thursday, March 23, 1989, 23:15
  7.  
  8.      Copyright © 1989-1994, Juri Munkki
  9. /*/
  10.  
  11. #include "VA.h"
  12. #include "STORM.h"
  13. #include "STCrack.h"
  14. #include "PlayOptions.h" 
  15. #include "HighScores.h"    /* mz */
  16. #include "heroflags.h"
  17.  
  18. #define    PLAYERMAXMOVE    (ThisLevel.plMaxMove)
  19. #define    DROPSPEED        (5)
  20. #define    POSTMORTEMTIMER    (60)
  21. #define    NEXTBLOWTIMER    (2)
  22. #define    SENSITIVITY        (PlayOptions->mouseSensitivity)
  23. #define    MAXRECORDSTEPS    (400)
  24. #define freeLifeScore    (20000) /* (mz) */
  25. #define MAXLIVES        (5) /* (mz) */
  26.  
  27. typedef    struct
  28. {
  29.     long    seed;
  30.     long    frameCounter;
  31.     long    count;
  32.     int        levelNumber;
  33.     char    moveData[MAXRECORDSTEPS];
  34. }    PlayRecordType;
  35.  
  36. int                PlayKeyCodes[4];    /*    right, left, fire, zap    */
  37. PlayRecordType    *PlayRecord;
  38. int                RecordStatus;
  39. int                RecordCount;
  40. Handle            RecordedHandle;
  41.  
  42. int        HeroShifts[]={ 1,2,3,4,4,5,6,7 };
  43.  
  44. extern    Point            MTemp            : 0x828;
  45. extern    Point            RawMouse        : 0x82c;
  46. extern    Point            Mouse            : 0x830;
  47. extern    int                CrsrNewCouple    : 0x8ce;
  48. extern    EventRecord        Event;
  49.  
  50. extern    Initials    *HiScoresToBeat;
  51. extern    int         ScoretoBeatIndex;
  52.  
  53.         Point        CenterMouse;
  54. static    int            cumulativerr=0;
  55.  
  56.         Player        Hero;
  57.  
  58.  
  59.  
  60. static    Point        ScorePosition;
  61. static    int            ScoreSegmentScale;
  62.  
  63. void    DisplayLives()
  64. {
  65.     register    int        i;
  66.     register    int        x,y,dx,sx;
  67.     
  68.     dx = ScoreSegmentScale + ScoreSegmentScale;
  69.     sx = (dx+dx+dx)>>2;    /*    dx*3/4    */
  70.  
  71.     x = ScoreSegmentScale;
  72.     y = ScorePosition.v+ScoreSegmentScale;
  73.  
  74.     VA.field= 2;
  75.     VA.offset=0;
  76.     VA.color= 0;
  77.     for(i=0;i<Hero.lives;i++)
  78.     {    DrawStaticPlayer(x,y,sx,0);
  79.         x+=dx;
  80.     }
  81. }
  82.  
  83. void    RemoveLife()
  84. {
  85.     register    int        x,y,dx,sx;
  86.     
  87.     Hero.lives--;
  88.  
  89.     if(Hero.lives < 8 && Hero.lives>=0)
  90.     {    dx = ScoreSegmentScale + ScoreSegmentScale;
  91.         sx = (dx+dx+dx)>>2;    /*    dx*3/4    */
  92.     
  93.         x = ScoreSegmentScale+dx*Hero.lives;
  94.         y = ScorePosition.v+ScoreSegmentScale;
  95.         
  96.         VA.field=2;
  97.         VA.offset=0;
  98.         VA.color=-1;
  99.         
  100.         DrawStaticPlayer(x,y,sx,0);
  101.     }
  102. }
  103. void    AddLife()
  104. {
  105.     register    int        x,y,dx,sx;
  106.     
  107.     if(Hero.lives < 8 && Hero.lives>=0)
  108.     {    dx = ScoreSegmentScale + ScoreSegmentScale;
  109.         sx = (dx+dx+dx)>>2;    /*    dx*3/4    */
  110.     
  111.         x = ScoreSegmentScale+dx*Hero.lives;
  112.         y = ScorePosition.v+ScoreSegmentScale;
  113.         
  114.         VA.field=2;
  115.         VA.offset=0;
  116.         VA.color=0;
  117.         
  118.         DrawStaticPlayer(x,y,sx,0);
  119.     }
  120.  
  121.     Hero.lives++;
  122. }
  123.  
  124. void    DisplayScore()
  125. {
  126.     VA.color=BG1;
  127.     VA.segmscale=ScoreSegmentScale;
  128.     VADrawNumber(Hero.score,ScorePosition.h,ScorePosition.v);
  129. }
  130.  
  131. void    ZeroScore()
  132. {
  133.     ScoreSegmentScale=VA.frame.bottom>>5;
  134.     if(ScoreSegmentScale<1)
  135.         ScoreSegmentScale=1;
  136.     do
  137.     {
  138.         ScorePosition.h=(ScoreSegmentScale+7)*8+10;
  139.         ScorePosition.v=ScoreSegmentScale+ScoreSegmentScale+4;
  140.     }    while((ScorePosition.h>VA.frame.right/3) & (ScoreSegmentScale-- > 0));
  141.     
  142.     ScoreSegmentScale++;
  143.  
  144.     if(!(Hero.Flags & SavedGameStartMask))
  145.     {
  146.         Hero.score=0;
  147.         Hero.lives=2;
  148.         Hero.freeLives = freeLifeScore; /* reset free life score to freeLifeScore (mz) */    
  149.         Hero.Flags = 0;    /* init new game flag */
  150.     }
  151.     Hero.state=HeroPlaying;
  152. }
  153.  
  154. void    IncreaseScore(points)
  155. long    points;
  156. {
  157.  
  158.     int            flashcount;
  159.     
  160.     Hero.score+=points;
  161.     Hero.drawscore= 1;
  162.     if (Hero.score > Hero.freeLives)         /* check for free life (mz)     */
  163.     {    
  164.         if(Hero.lives < MAXLIVES || (Hero.lives <= MAXLIVES && Hero.state==HeroFlying))    
  165.                                             /* no more than MAXLIVES lives     */
  166.         {
  167.             if(Hero.Flags & 0x0010)
  168.             {
  169.                 PlayB(ZZFreeLife,999);        /* play free life sound (mz)     */
  170.                 if((!PlayOptions->noLoudSounds)&&(Hero.state!=HeroFlying))
  171.                     PlayA(ZZFreeLife,999);
  172.                 Hero.Flags |= 0x0001;         /* set flash flag (mz)         */
  173.             }
  174.             AddLife();
  175.         }
  176.         Hero.freeLives = Hero.score - (Hero.score % freeLifeScore) + freeLifeScore;
  177.         /* round score up to next interval */
  178.     }
  179.     
  180.     if (Hero.score > HiScoresToBeat[ScoretoBeatIndex].score)
  181.     {
  182.         unsigned char    *namestr=(void *)"SCORE";
  183.         unsigned char    position[3];
  184.         long    scoretobeat;
  185.         int        hsc=VA.color;
  186.         int        x;
  187.         
  188.         while ((Hero.score > HiScoresToBeat[ScoretoBeatIndex].score) && ScoretoBeatIndex>=1)
  189.             ScoretoBeatIndex--;
  190.         if (ScoretoBeatIndex < 1) /* player now has top score */
  191.         {    scoretobeat = Hero.score;
  192.             ScoretoBeatIndex = 1;
  193.             
  194.             position[0] = 'H';
  195.             position[1] = 'I';
  196.         }
  197.         else
  198.         {    position[1] = ScoretoBeatIndex % 10 + '0';
  199.             if(ScoretoBeatIndex >= 10)
  200.                 position[0] = ScoretoBeatIndex / 10 + '0';
  201.             else
  202.                 position[0] = ' ';
  203.         
  204.             scoretobeat = HiScoresToBeat[ScoretoBeatIndex].score;
  205.             namestr = HiScoresToBeat[ScoretoBeatIndex].name; 
  206.         }
  207.             
  208.         position[2] = '-';
  209.         
  210.         VA.color = BG2; 
  211.         if (ThisLevel.lvColor == 5)        /* check for invis lvl where BG2 is */
  212.             VA.color=BG1;                /* also invis. (mz)                 */
  213.         
  214.         VA.segmscale = 1+(ScoreSegmentScale >> 3);
  215.         x = VA.frame.right - 1 - 8*(VA.segmscale*3+3);
  216.  
  217.         VAMoveTo(x,(VA.segmscale << 2)+4);
  218.         VADrawText((char *) position,0,3);
  219.         VADrawText((char *) namestr,0,5);
  220.         
  221.         VA.segmscale += VA.segmscale;
  222.         x = VA.frame.right - (VA.segmscale + 7) + 1;      /* was - 10 */
  223.         VADrawPadNumber(scoretobeat,x,(VA.segmscale*6)+5,8); 
  224.         
  225.         VA.color = hsc;
  226.     }    /* end if */
  227. }
  228.  
  229. void    UpdateEdgeLines()
  230. {
  231.     register    int        i;
  232.     register    int        savedfield=VA.field;
  233.     register    int        savedoffset=VA.offset;
  234.     
  235.     VA.field=1;
  236.     VA.offset=1;
  237.     
  238.     for(i=0;i<ww.numsegs;i++)
  239.     {
  240.         if(Hero.lanemissing[i])
  241.         {    if(!(Hero.lanestat[i] & PulsMask))        
  242.             {    VA.color=0;        
  243.                 Hero.lanemissing[i]=0;
  244.                 VAStaticLine(ww.x[i][0],ww.y[i][0],ww.x[i+1][0],ww.y[i+1][0]);
  245.             }
  246.         }
  247.         else
  248.         {    if((Hero.lanestat[i] & PulsMask))        
  249.             {    VA.color=1;
  250.                 Hero.lanemissing[i]=1;
  251.                 VAStaticLine(ww.x[i][0],ww.y[i][0],ww.x[i+1][0],ww.y[i+1][0]);
  252.             }
  253.         }
  254.     }
  255. }
  256. void    CrackPlayer()
  257. {
  258.     register    int        angle,delta;
  259.     register    int        x,y,dx,dy;
  260.                 int        x2,y2;
  261.     
  262.     x = ww.x[Hero.lane][0];
  263.     y = ww.y[Hero.lane][0];
  264.     
  265.     x2 = ww.x[Hero.lane+1][0];
  266.     y2 = ww.y[Hero.lane+1][0];
  267.     
  268.     dx = x-x2;
  269.     dy = y-y2;
  270.  
  271.     delta = ww.unitlen[0]*4/3;
  272.     angle = NextSeg[Hero.lane];
  273.  
  274.     AddCrack(    x,y,
  275.                 (dx>>3)-(dy>>2),(dy>>3)+(dx>>2),
  276.                 ThisLevel.shColor[0],delta,PlayerLeft,
  277.                 angle,4,POSTMORTEMTIMER);
  278.     
  279.     angle = ANGLES-angle;
  280.     if(angle>=ANGLES)    angle-=ANGLES;
  281.     
  282.     AddCrack(    x2,y2,
  283.                 -(dx>>3)-(dy>>2),-(dy>>3)+(dx>>2),
  284.                 ThisLevel.shColor[0],delta,PlayerRight,
  285.                 angle,4,POSTMORTEMTIMER);        
  286. }
  287.  
  288. void    NukePlayer()
  289. {
  290.     VA.color=ThisLevel.shColor[0];    /*    Shot color 0 is player also color.    */
  291.     BlowUpPlayer(    ww.x[Hero.lane][Hero.dropdepth],ww.y[Hero.lane][Hero.dropdepth],
  292.                     ww.x[Hero.lane+1][Hero.dropdepth]-ww.x[Hero.lane][Hero.dropdepth],
  293.                     ww.y[Hero.lane+1][Hero.dropdepth]-ww.y[Hero.lane][Hero.dropdepth],Hero.shifter);
  294.  
  295. }
  296. void    PlayerCapture(status)
  297. register    int        status;
  298. {
  299.     if(status & FlipMask)
  300.     {    Hero.state = HeroDropping;
  301.         PlayB(FallYell,999);  
  302.         if(!PlayOptions->noLoudSounds)
  303.             PlayA(FallYell,999);
  304.     }
  305.     else
  306.     if(status & PulsMask)
  307.     {    Hero.state=HeroPostMortem;
  308.         Hero.timer=POSTMORTEMTIMER;
  309.  
  310.         CrackPlayer();
  311.         NukePlayer();
  312.  
  313.         PlayB(FallZap,999);
  314.         if(!PlayOptions->noLoudSounds)
  315.             PlayB(FallZap,999);
  316.     }
  317.     else
  318.     if(status & FuseMask)
  319.     {    Hero.state=HeroDisintegrating;
  320.         Hero.timer=NEXTBLOWTIMER;
  321.         NukePlayer();
  322.         PlayB(FallZap,999);
  323.         if(!PlayOptions->noLoudSounds)
  324.             PlayB(FallZap,999);
  325.     }
  326.     else if(status & PlasMask)
  327.     {    Hero.state=HeroDisintegrating;
  328.         Hero.timer=NEXTBLOWTIMER;
  329.         NukePlayer();
  330.         PlayB(PhazerOut,999);
  331.         PlayA(PhazerOut,999);
  332.     }
  333.     else if(status & SpikeMask)
  334.     {    Hero.state=HeroPostMortem;
  335.         Hero.timer=POSTMORTEMTIMER;
  336.         CrackPlayer();
  337.         PlayB(FallZap,999);
  338.         if(!PlayOptions->noLoudSounds)
  339.             PlayA(FallZap,999);
  340.     }
  341.     
  342.     cumulativerr=0;
  343. }
  344.  
  345. void    GetSetMouse(where)
  346. register    Point    *where;
  347. {
  348.     Point    oldwhere;
  349.  
  350.     oldwhere=Mouse;
  351.     
  352.     RawMouse=*where;
  353.     MTemp=*where;
  354.     CrsrNewCouple=-1;
  355.     
  356.     where->h=oldwhere.h-where->h;
  357.     where->v=oldwhere.v-where->v;
  358. }
  359.  
  360. void    WannaShoot(enable)
  361. int        enable;
  362. {
  363.     if(enable)
  364.     {    Hero.couldshoot=-1;
  365.         if(!(Event.modifiers & btnState) || Hero.pendingshot)
  366.         {    if(AddShot(Hero.lane))
  367.                 PlayA(PhazerIn,2);
  368.             Hero.pendingshot=0;
  369.         }
  370.     }
  371.     else    
  372.     {    Hero.couldshoot=0;
  373.         Hero.pendingshot=(Event.what==mouseDown);
  374.     }
  375. }
  376.  
  377. void    TextStuff(thecount)
  378. int        thecount;
  379. {
  380.     int        stringid;
  381.     Handle    TheString;
  382.     char    *strp;
  383.     int        totalwidth;
  384.     char    empty[256];
  385.     
  386.     static    int        oldx;
  387.     static    int        oldy;
  388.     static    int        thelen;
  389.     static    int        thescale;
  390.     
  391.     thecount += 64;
  392.  
  393.     if((thecount & 127)==0)
  394.     {    if(thecount == 128)
  395.         {    thelen = 0;
  396.             oldx = 0;
  397.             oldy = 0;
  398.         }
  399.  
  400.         thescale = ScoreSegmentScale/4;
  401.         if(thescale < 1) thescale = 1;
  402.         VA.segmscale = thescale;
  403.         
  404.         if(thelen)
  405.         {    VAMoveTo(oldx,oldy);
  406.             for(totalwidth=0;totalwidth<thelen;totalwidth++)
  407.             {    empty[totalwidth]=' ';
  408.             }
  409.             VADrawText(empty,0,thelen);
  410.         }
  411.  
  412.         stringid = 128+(thecount>>7);
  413.         if(stringid < 132)
  414.         {    TheString = (Handle)GetString(stringid);
  415.             HLock(TheString);
  416.             strp = *TheString;
  417.             thelen = *strp;    
  418.  
  419.             totalwidth = thelen * (thescale * 3 + 3);
  420.  
  421.             oldx = (VA.frame.right-VA.frame.left - totalwidth)/2;
  422.             oldy = VA.frame.bottom-(thescale << 3);
  423.             VAMoveTo(oldx,oldy);
  424.  
  425.             VA.color = BG1;
  426.             VADrawText(strp,1,thelen);
  427.             
  428.             HUnlock(TheString);
  429.             ReleaseResource(TheString);
  430.         }
  431.     }
  432. }
  433.  
  434. void    UpdatePlayer()
  435. {
  436.                 Point    mouse;
  437.     register    int        delta;
  438.     register    int        i,j;
  439.     register    int        rotationtype;
  440.     register    int        steps=ww.numsegs*8;
  441.                 int        shootenable;
  442.                 int        DrawPlayerFlag;
  443.                 long    KeyboardFlags[4];
  444.  
  445.                 Handle        ZapColorsHandle;
  446.                 ColorSpec    *ColorTable;
  447.     
  448.     
  449.     if(Hero.state!=HeroFlying && Hero.state!=HeroPostMortem)
  450.         UpdateEdgeLines();
  451.  
  452.     rotationtype = PlayOptions->rotationType;
  453.  
  454.     if(PlayOptions->absMoveFlag)
  455.     {
  456.         mouse=CenterMouse;
  457.         GetSetMouse(&mouse);
  458.         
  459.         if(rotationtype < 2)    delta=  mouse.h;
  460.         else                    delta= -mouse.v;
  461.         
  462.         if(rotationtype & 1)    delta = -delta;
  463.  
  464.         delta = ((delta*SENSITIVITY) >> 3) + cumulativerr;
  465.     }
  466.     else
  467.     {
  468.         long    hort,vort;
  469.         int        lane1,lane2;
  470.         
  471.         mouse=CenterMouse;
  472.         GetSetMouse(&mouse);
  473.         
  474.         lane1=Hero.lane-1;
  475.         lane2=Hero.lane+2;
  476.         if(ww.wraps)
  477.         {    if(lane1<0)             lane1 += ww.numsegs;
  478.             if(lane2>ww.numsegs)     lane2 -= ww.numsegs;
  479.         }
  480.         else
  481.         {    if(lane1<0)                lane1 = 0;
  482.             if(lane2>ww.numsegs)    lane2 = ww.numsegs;
  483.         }
  484.         hort=ww.x[lane2][0]-ww.x[lane1][0];
  485.         vort=ww.y[lane2][0]-ww.y[lane1][0];
  486.         
  487.         hort *= mouse.h;
  488.         vort *= mouse.v;
  489.         
  490.         delta=(mouse.h<0 ? mouse.h : -mouse.h) +
  491.               (mouse.v<0 ? mouse.v : -mouse.v);
  492.  
  493.         if(hort+vort > 0)
  494.         {    delta = -delta;
  495.         }
  496.         
  497.         delta = ((delta*SENSITIVITY) >> 3);
  498.     }
  499.     
  500.     GetKeys(KeyboardFlags);    
  501.     if(BitTst(KeyboardFlags,PlayKeyCodes[0]))
  502.     {    delta = SENSITIVITY;
  503.     }
  504.     else
  505.     if(BitTst(KeyboardFlags,PlayKeyCodes[1]))
  506.     {    delta = -SENSITIVITY;
  507.     }
  508.     
  509.     if(BitTst(KeyboardFlags,PlayKeyCodes[2]))
  510.     {    Hero.pendingshot = 1;
  511.     }
  512.  
  513.     if(Hero.state == HeroFlying || Hero.state == HeroPlaying)
  514.     {    
  515.         cumulativerr=delta;
  516.         
  517.         if(delta>PLAYERMAXMOVE) delta=PLAYERMAXMOVE;
  518.         if(delta<-PLAYERMAXMOVE) delta=-PLAYERMAXMOVE;
  519.     
  520.         if(RecordStatus != NormalPlay)
  521.         {    TextStuff(RecordCount);
  522.             if(RecordStatus == RecordPlay)
  523.             {    if(RecordCount < MAXRECORDSTEPS)
  524.                 {    PlayRecord->moveData[RecordCount] = (delta << 2) +
  525.                             ((!(Event.modifiers & btnState) || Hero.pendingshot) ? 1 : 0) +
  526.                             ((Event.what==keyDown && BitTst(KeyboardFlags,PlayKeyCodes[3])) ?
  527.                              2 : 0);
  528.                         
  529.                     RecordCount++;
  530.                     PlayRecord->count = RecordCount;
  531.                 }
  532.                 else
  533.                 {    RecordStatus = NormalPlay;
  534.                     Hero.state = HeroDead;
  535.                     Hero.lives = 0;
  536.                 }
  537.             }
  538.             else
  539.             {    KeyboardFlags[0] = 0;
  540.                 KeyboardFlags[1] = 0;
  541.                 KeyboardFlags[2] = 0;
  542.                 KeyboardFlags[3] = 0;
  543.  
  544.                 if(RecordCount < PlayRecord->count)
  545.                 {    delta = PlayRecord->moveData[RecordCount];
  546.                     RecordCount++;
  547.                     Hero.pendingshot = delta & 1;
  548.                     Event.modifiers |=  btnState;
  549.                     if(delta & 2)
  550.                     {    Event.what=keyDown;
  551.                         BitSet(KeyboardFlags,PlayKeyCodes[3]);
  552.                     }
  553.                     delta >>= 2;
  554.                 }
  555.                 else
  556.                 {    RecordStatus = NormalPlay;
  557.                     Hero.state = HeroDead;
  558.                     Hero.lives = 0;
  559.                 }
  560.             }
  561.         }
  562.  
  563.         cumulativerr-=delta;
  564.         Hero.rawpos+=delta;
  565.  
  566.         if(Hero.rawpos<0)
  567.         {    if(ww.wraps)
  568.             {    while(Hero.rawpos<0)
  569.                 {    Hero.rawpos+=steps;
  570.                 }
  571.             }
  572.             else
  573.                 Hero.rawpos=0;
  574.         }
  575.         else
  576.         if(Hero.rawpos>=steps)
  577.         {    if(ww.wraps)
  578.             {    while(Hero.rawpos>=steps)
  579.                 {    Hero.rawpos-=steps;
  580.                 }
  581.             }
  582.             else
  583.                 Hero.rawpos=steps-1;
  584.         }
  585.     
  586.         Hero.shifter=HeroShifts[Hero.rawpos & 7];
  587.         Hero.lane=Hero.rawpos / 8;
  588.     
  589.         shootenable=Hero.oldlane != Hero.lane || (VA.FrameCounter & 1);
  590.  
  591.         if(Hero.lanestat[Hero.oldlane])
  592.         {    Hero.lane=Hero.oldlane;
  593.             PlayerCapture(Hero.lanestat[Hero.oldlane]);
  594.         }
  595.     }
  596.     
  597.  
  598.     DrawPlayerFlag = !VA.Late;
  599.     
  600.     switch(Hero.state)
  601.     {    case HeroDropping:
  602.             Hero.dropdepth+=(Hero.dropdepth>>3)+DROPSPEED;
  603.             if(Hero.dropdepth>=DEPTH)
  604.             {    Hero.state=HeroPostMortem;
  605.                 Hero.timer=POSTMORTEMTIMER;
  606.                 Hero.dropdepth=DEPTH;
  607.                 NukePlayer();
  608.                 PlayB(Blow,100);
  609.             }
  610.             else
  611.             {    DrawPlayerFlag=1;
  612.             }
  613.             break;
  614.         case HeroDisintegrating:
  615.             DrawPlayerFlag=0;
  616.             Hero.timer--;
  617.             if(Hero.timer<=0)
  618.             {    Hero.state=HeroPostMortem;
  619.                 Hero.timer=POSTMORTEMTIMER;
  620.                 Hero.shifter = (Hero.shifter+4) & 7;
  621.                 NukePlayer();
  622.             }
  623.             break;
  624.         case HeroPostMortem:
  625.             DrawPlayerFlag=0;
  626.  
  627.             Hero.timer--;
  628.             if(Hero.timer<=0)
  629.             {    Hero.state=HeroDead;
  630.             }
  631.             break;
  632.         default:
  633.             DrawPlayerFlag=1;
  634.             break;
  635.     }
  636.  
  637.     if(Hero.oldlane!=Hero.lane)
  638.     {    PlayA(Bonk,1);
  639.         i = (delta>0) ? 1 : -1;
  640.         j = (delta>0) ? 1 : 0;
  641.         while(Hero.oldlane!=Hero.lane)
  642.         {    if(Hero.segmstat[Hero.oldlane+j] || Hero.lanestat[Hero.oldlane])
  643.             {    if(Hero.segmstat[Hero.oldlane+j])
  644.                 {    Hero.lane=Hero.oldlane+j;
  645.                     PlayerCapture(Hero.segmstat[Hero.lane]);
  646.                 }
  647.                 Hero.lane=Hero.oldlane;
  648.                 if(Hero.lanestat[Hero.oldlane])
  649.                     PlayerCapture(Hero.lanestat[Hero.oldlane]);
  650.             }
  651.             else
  652.             {    Hero.oldlane+=i;
  653.                 if(Hero.oldlane<0)
  654.                 {    Hero.oldlane=ww.numsegs-1;
  655.                 }
  656.                 else
  657.                 if(Hero.oldlane>=ww.numsegs)
  658.                 {    Hero.oldlane=0;
  659.                 }
  660.             }
  661.         }
  662.     }
  663.  
  664.     if(DrawPlayerFlag)
  665.     {    VA.color=ThisLevel.shColor[0];    /*    Shot color 0 is player also color.    */
  666.         DrawPlayer(    ww.x[Hero.lane][Hero.dropdepth],ww.y[Hero.lane][Hero.dropdepth],
  667.                     ww.x[Hero.lane+1][Hero.dropdepth]-ww.x[Hero.lane][Hero.dropdepth],
  668.                     ww.y[Hero.lane+1][Hero.dropdepth]-ww.y[Hero.lane][Hero.dropdepth],Hero.shifter);
  669.         
  670.         if(Hero.flydepth==0)
  671.         {    VALine(    ww.x[Hero.lane][Hero.dropdepth],ww.y[Hero.lane][Hero.dropdepth],
  672.                         ww.x[Hero.lane][DEPTH],ww.y[Hero.lane][DEPTH]);
  673.             VALine(    ww.x[Hero.lane+1][Hero.dropdepth],ww.y[Hero.lane+1][Hero.dropdepth],
  674.                         ww.x[Hero.lane+1][DEPTH],ww.y[Hero.lane+1][DEPTH]);
  675.         } 
  676.     }
  677.         
  678.     /* if lower 4 bits !=0 then colors are being flashed.  Counts up to 12    */
  679.     /* so it cycles thru the CLOT's twice modulo 6, then reset to 0. (mz)    */
  680.         
  681.     if((Hero.superzapping==1 || Hero.Flags & 0x000F) && Hero.state != HeroFlying) 
  682.     {    
  683.         if ( (!(Hero.Flags & 0x000F)) || (Hero.Flags & 0x000C)==0x000C ) 
  684.         {
  685.             /* flashing is done    */
  686.             ZapColorsHandle=GetResource('CLOT',ThisLevel.lvColor);
  687.             Hero.Flags &= 0x7FF0;
  688.         }
  689.         else{ /* run through all colors to enhance flash (mz) */
  690.             ZapColorsHandle=GetResource('CLOT',((Hero.Flags & 0x000F) % 6 + 1));
  691.             Hero.Flags++;
  692.         }
  693.         VASetColors(ZapColorsHandle);
  694.         ReleaseResource(ZapColorsHandle);
  695.     }
  696.  
  697.     if(Hero.state == HeroPlaying)
  698.     {    Hero.superzapping=0;
  699.         if(Event.what==keyDown && BitTst(KeyboardFlags,PlayKeyCodes[3]))
  700.         {    if(ThisLevel.plSuperZaps>0)
  701.             {    ThisLevel.plSuperZaps--;
  702.                 Hero.superzapping= 1;
  703.                 PlayB(ZZSuperZap,998);     /* mz */
  704.                 if(!PlayOptions->noLoudSounds)
  705.                     PlayA(ZZSuperZap,998);
  706.                 ZapColorsHandle=VAGetColors();
  707.  
  708.                 ColorTable=(void *)(*ZapColorsHandle);
  709.                 ColorTable[8].rgb.red=65535;
  710.                 ColorTable[8].rgb.green=65535;
  711.                 ColorTable[8].rgb.blue=65535;
  712.                 VASetColors(ZapColorsHandle);
  713.                 DisposHandle(ZapColorsHandle);
  714.             }
  715.             else
  716.             if(ThisLevel.plSuperZaps==0)
  717.             {    ThisLevel.plSuperZaps--;
  718.                 Hero.superzapping= 2;
  719.             }
  720.         }
  721.     }
  722.     if(Hero.state == HeroPlaying || Hero.state == HeroFlying)
  723.         WannaShoot(shootenable);
  724.  
  725.     for(i=0;i<ww.numsegs;i++)
  726.     {    Hero.lanestat[i]=0;
  727.         Hero.segmstat[i]=0;
  728.     }
  729.     Hero.segmstat[i]=0;
  730.     
  731.     if(Hero.drawscore)
  732.         DisplayScore();
  733. }
  734.  
  735. void    InitPlayer()
  736. {
  737.     register    int        i;
  738.                 Point    foo;
  739.     
  740.     BlockMove(*GetResource('KEYS',128),PlayKeyCodes,8);
  741.     CenterMouse.h=(VA.DisplayFrame.right+VA.DisplayFrame.left)/2;
  742.     CenterMouse.v=(VA.DisplayFrame.bottom+VA.DisplayFrame.top)/2;
  743.     
  744.     foo=CenterMouse;
  745.     GetSetMouse(&foo);
  746.     cumulativerr=0;
  747.     
  748.     Hero.flydepth=0;
  749.     Hero.dropdepth=0;
  750.     Hero.state=HeroPlaying;
  751.     Hero.timer=0;
  752.     
  753.     for(i=0;i<MAXSEGS;i++)
  754.     {    Hero.lanestat[i]=0;
  755.         Hero.segmstat[i]=0;
  756.         Hero.lanemissing[i]=0;
  757.     }
  758.     Hero.segmstat[MAXSEGS]=0;
  759.     Hero.endtimer=ThisLevel.endTimer;
  760. }
  761.  
  762. void    StartPlayRecord()
  763. {
  764.     RecordStatus = RecordPlay;
  765.     RecordCount = 0;
  766.     PlayRecord->count = 0;
  767.     PlayRecord->seed = VARandSeed;
  768.     PlayRecord->frameCounter = VA.FrameCounter;
  769.     PlayRecord->levelNumber = ThisLevel.lvNext;
  770.  
  771.     Hero.lane = 0;
  772.     Hero.shifter = 0;
  773.     Hero.rawpos = 0;
  774. }
  775. void    StartPlayback()
  776. {
  777.     RecordStatus = PlaybackPlay;
  778.     RecordCount = 0;
  779.     VARandSeed = PlayRecord->seed;
  780.     VA.FrameCounter = PlayRecord->frameCounter;
  781.     ThisLevel.lvNext = PlayRecord->levelNumber;
  782.     Hero.lane = 0;
  783.     Hero.shifter = 0;
  784.     Hero.rawpos = 0;
  785. }
  786. void    StartNormalPlay()
  787. {
  788.     RecordStatus = NormalPlay;
  789. }
  790.  
  791. void    LoadPlayRecord()
  792. {
  793.     RecordedHandle = GetResource('MYGA',128+((ThisLevel.lvNext>>1) & 7));
  794.     if(GetHandleSize(RecordedHandle) != sizeof(PlayRecordType))
  795.     {    SetHandleSize(RecordedHandle,sizeof(PlayRecordType));
  796.     }
  797.     HLock(RecordedHandle);
  798.  
  799.     PlayRecord = (PlayRecordType *)*RecordedHandle;
  800. }
  801.  
  802. void    UnloadPlayRecord()
  803. {
  804.     HUnlock(RecordedHandle);
  805.     ReleaseResource(RecordedHandle);
  806. }
  807.  
  808. void    WriteRecordedPlay()
  809. {
  810.     ChangedResource(RecordedHandle);
  811.     WriteResource(RecordedHandle);
  812. }